﻿using Markdig;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SQLiteCoreDB;
using SQLiteCoreDB.Models;
using System.IO.Abstractions;
using WebFile.Filter;
using WebFile.Models;

namespace WebFile.Controllers
{

    public class HomeController : Controller
    {
        private readonly IFileSystem _fileSystem;

        public HomeController(IFileSystem fileSystem)
        {
            _fileSystem = fileSystem;
        }


        MarkdownReader md = SC<MarkdownReader>.I;
        public ActionResult Index(int pageIndex = 1, int pageSize = 20)
        {

            var userList = SL.db.ChatUser;
            ViewBag.TotalItems = userList.Count();
            int totalPages = (int)Math.Ceiling((double)ViewBag.TotalItems / pageSize);

            List<ChatUser> List = userList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();

            ViewBag.pageIndex = pageIndex;
            ViewBag.pageSize = pageSize;
            return View(userList);
        }

        //文件浏览入口

        public IActionResult FileList()
        {
            string dirNew = Path.Combine(KeyValueConfig.FileSaveDir);
            if (!_fileSystem.Directory.Exists(dirNew))
            {
                _fileSystem.Directory.CreateDirectory(dirNew);
            }
            var list = _fileSystem.Directory.GetFileSystemEntries(KeyValueConfig.FileSaveDir);
            List<FileInfoMy> listMy = new List<FileInfoMy>();
            foreach (var item in list)
            {
                var createDatetime = _fileSystem.File.GetCreationTime(item);
                bool isDir = _fileSystem.Directory.Exists(item);
                var attri = _fileSystem.File.GetAttributes(item);
                long bytes = 0;
                string fileSize = string.Empty;
                if (isDir)
                {
                }
                else //if (attri == FileAttributes.Normal)
                {
                    FileInfo fileInfo = new FileInfo(item);
                    bytes = fileInfo.Length;

                    decimal kb = Math.Round(bytes / (decimal)1024, 2);
                    if (kb < 1024)
                    {
                        fileSize = kb + " KB";
                        goto Calc_file_size;
                    }
                    decimal mb = Math.Round(kb / 1024, 2);
                    if (mb < 1024)
                    {
                        fileSize = mb + " MB";
                        goto Calc_file_size;
                    }
                    decimal GB = Math.Round(mb / 1024, 2);
                    fileSize = GB + " GB";
                }
                Calc_file_size:
                FileInfoMy info = new FileInfoMy();
                info.FileType = attri;
                info.CreateTime = createDatetime;
                info.FileName = Path.GetFileName(item);
                info.FileNamePath = item.Replace(KeyValueConfig.FileSaveDir, "").Replace("\\", "/").TrimStart('/');
                info.FileSize = fileSize;
                listMy.Add(info);
            }
            listMy = listMy.OrderBy(x => x.FileType).ToList();
            if (!LoginMode.admin || (LoginMode.admin && !LoginMode.LV.Equals("1")))
            {
                var fileUser = SL.db.FileUser.ToList();
                listMy = listMy.Where(x => !fileUser.Any(y => y.FileName.Equals(x.FileName) && y.UserName != LoginMode.username)).ToList();
            }
            ViewBag.listMy = listMy;

            return View();
        }
        //文件浏览入口

        public IActionResult GetFileList()
        {
            string dirNew = Path.Combine(KeyValueConfig.FileSaveDir);
            if (!_fileSystem.Directory.Exists(dirNew))
            {
                _fileSystem.Directory.CreateDirectory(dirNew);
            }
            var list = _fileSystem.Directory.GetFileSystemEntries(KeyValueConfig.FileSaveDir);
            List<FileInfoMy> listMy = new List<FileInfoMy>();
            foreach (var item in list)
            {
                var createDatetime = _fileSystem.File.GetCreationTime(item);
                bool isDir = _fileSystem.Directory.Exists(item);
                var attri = _fileSystem.File.GetAttributes(item);
                long bytes = 0;
                string fileSize = string.Empty;
                if (isDir)
                {
                }
                else //if (attri == FileAttributes.Normal)
                {
                    FileInfo fileInfo = new FileInfo(item);
                    bytes = fileInfo.Length;

                    decimal kb = Math.Round(bytes / (decimal)1024, 2);
                    if (kb < 1024)
                    {
                        fileSize = kb + " KB";
                        goto Calc_file_size;
                    }
                    decimal mb = Math.Round(kb / 1024, 2);
                    if (mb < 1024)
                    {
                        fileSize = mb + " MB";
                        goto Calc_file_size;
                    }
                    decimal GB = Math.Round(mb / 1024, 2);
                    fileSize = GB + " GB";
                }
                Calc_file_size:
                FileInfoMy info = new FileInfoMy();
                info.FileType = attri;
                info.CreateTime = createDatetime;
                info.FileName = Path.GetFileName(item);
                info.FileNamePath = item.Replace(KeyValueConfig.FileSaveDir, "").Replace("\\", "/").TrimStart('/');
                info.FileSize = fileSize;
                listMy.Add(info);
            }
            listMy = listMy.OrderBy(x => x.FileType).ToList();
            if (!LoginMode.admin || (LoginMode.admin && !LoginMode.LV.Equals("1")))
            {
                var fileUser = SL.db.FileUser.ToList();
                listMy = listMy.Where(x => !fileUser.Any(y => y.FileName.Equals(x.FileName) && y.UserName != LoginMode.username)).ToList();
            }
            ViewBag.listMy = listMy;

            return PartialView("../Home/ModeList");
        }

        //点击查看目录

        public IActionResult SeeDir(string dirNew, DirType Dir = DirType.View)
        {
            dirNew = dirNew?.TrimStart('/') ?? "";
            ViewBag.dirNew = dirNew;

            string dirInput = Path.Combine(KeyValueConfig.FileSaveDir, dirNew);
            var list = _fileSystem.Directory.GetFileSystemEntries(dirInput);
            List<FileInfoMy> listMy = new List<FileInfoMy>();
            foreach (var item in list)
            {
                var createDatetime = _fileSystem.File.GetCreationTime(item);

                bool isDir = _fileSystem.Directory.Exists(item);

                long bytes = 0;
                string fileSize = string.Empty;
                if (isDir)
                {
                }
                else
                {
                    FileInfo fileInfo = new FileInfo(item);
                    bytes = fileInfo.Length;

                    decimal kb = Math.Round(bytes / (decimal)1024, 2);
                    if (kb < 1024)
                    {
                        fileSize = kb + " KB";
                        goto Calc_file_size;
                    }
                    decimal mb = Math.Round(kb / 1024, 2);
                    if (mb < 1024)
                    {
                        fileSize = mb + " MB";
                        goto Calc_file_size;
                    }
                    decimal GB = Math.Round(mb / 1024, 2);
                    fileSize = GB + " GB";
                }
                Calc_file_size:
                FileInfoMy info = new FileInfoMy();
                info.FileType = _fileSystem.File.GetAttributes(item);
                info.CreateTime = createDatetime;
                info.FileName = Path.GetFileName(item);
                info.FileNamePath = item.Replace(KeyValueConfig.FileSaveDir, "").Replace("\\", "/");
                info.FileSize = fileSize;
                listMy.Add(info);
            }
            listMy = listMy.OrderBy(x => x.FileType).ToList();
            if (!LoginMode.admin || (LoginMode.admin && !LoginMode.LV.Equals("1")))
            {
                var fileUser = SL.db.FileUser.ToList();
                listMy = listMy.Where(x => !fileUser.Any(y => y.FileName.Equals(x.FileName) && y.UserName != LoginMode.username)).ToList();
            }
            ViewBag.listMy = listMy;

            switch (Dir)
            {
                case DirType.View:
                    return View("FileList");
                case DirType.PartialView:
                    return PartialView("../Home/ModeList");
                default:
                    return View("FileList");
            }
        }

        //点击下载文件

        public IActionResult SeeFile(string file)
        {
            string file2 = file.TrimStart('/');
            string filePath = Path.Combine(KeyValueConfig.FileSaveDir, file2);
            filePath = Path.GetFullPath(filePath);

            string fileDownName = Path.GetFileName(file);
            int index = fileDownName.IndexOf('_');

            if (index >= 0 && index < fileDownName.Length - 1)
            {
                fileDownName = fileDownName.Substring(index + 1); // 获取从下划线后面开始的子字符串
                                                                  // 进一步处理子字符串...
            }

            #region 浏览器在线预览文件内容
            string extend = Path.GetExtension(file).ToLower();
            string mime = "application/octet-stream";
            switch (extend)
            {
                case ".jpg":
                case ".jfif":
                case ".gif":
                case ".png":
                case ".bmp":
                case ".ico":
                    mime = "image/jpeg";
                    break;
                case ".pdf":
                    mime = "application/pdf";
                    break;

                case ".xml":
                case ".config":
                    mime = "text/xml";
                    break;


                //case ".html":
                //    mime = "text/html";
                //    break;

                case ".css":
                    mime = "text/css";
                    break;
                case ".js":
                    mime = "text/javascript";
                    break;

                case ".html":
                case ".xaml":
                case ".cs":
                case ".txt":
                case ".ini":
                case ".md":
                    mime = "text/plain";
                    break;
                case ".mp4":
                    mime = "video/mp4";
                    break;
            }
            #endregion
            return PhysicalFile(filePath, mime, fileDownName);

        }


        public IActionResult DelFile(string file)
        {
            string file2 = file?.TrimStart('/') ?? "";
            string filePath = Path.Combine(KeyValueConfig.FileSaveDir, file2);

            try
            {
                if (_fileSystem.Directory.Exists(filePath))
                {
                    string[] files = _fileSystem.Directory.GetFiles(filePath);
                    if (files.Length == 0)
                    {
                        _fileSystem.Directory.Delete(filePath);  // 删除目录                   
                        return Json(new Result("删除成功", 1)); // 返回删除成功的结果
                    }
                    else
                    {
                        return Json(new Result("目录中存在文件，删除失败")); // 目录中存在文件，返回删除失败的结果
                    }
                }
                else if (_fileSystem.File.Exists(filePath))
                {
                    var fileUser = SL.db.FileUser.FirstOrDefault(x => x.FileName.Equals(file2));
                    if (fileUser != null)
                    {
                        SL.db.FileUser.Remove(fileUser);
                        SL.db.SaveChanges();
                    }




                    _fileSystem.File.Delete(filePath);// 删除文件
                                                      // 
                    return Json(new Result("删除成功", 1)); // 返回删除成功的结果
                }
                else
                {
                    return Json(new Result("文件或目录不存在")); // 文件或目录不存在，返回删除失败的结果
                }
            }
            catch (Exception ex)
            {
                // 返回删除失败的结果，并将异常信息返回给前端
                return Json(new Result("删除失败：" + ex.Message));
            }
        }

        //在线查看图片

        public ActionResult SeeImg(string file)
        {
            string file2 = file?.TrimStart('/') ?? "";
            string filePath = Path.Combine(KeyValueConfig.FileSaveDir, file2);
            //在线预览，必须设置为 image/jpeg
            return PhysicalFile(filePath, "image/jpeg");
        }




        public ActionResult UserList()
        {

            IQueryable<Login> users = SL.db.Login;
            List<Login> list = new List<Login>();
            if (LoginMode.LV != "1")
            {
                list = users.Where(x => !x.role.Equals("admin")).ToList();
            }
            else
            {
                list = users.ToList();
            }

            return View(list);
        }

        [AllowAnonymous]
        public ActionResult MDReader(string file, string title)
        {

            file = Path.Combine(KeyValueConfig.FileSaveDir, file);
            string htmlContent = md.Reader(file) ?? "出现错误，请检查文件内容或联系管理员";
            ViewData["Title"] = title ?? "文档";
            ViewData["HtmlContent"] = htmlContent;


            return View();
        }
        [SkipLoginFilter]
        public ActionResult WriteMD(string file, string title)
        {
            ViewData["FilePath"] = file;
            file = Path.Combine(KeyValueConfig.FileSaveDir, file);
            string htmlContent = md.Reader(file, true) ?? "出现错误，请检查文件内容或联系管理员";
            ViewData["Title"] = title ?? "文档";
            ViewData["HtmlContent"] = htmlContent;

            return View();
        }
        [SkipLoginFilter]
        public ActionResult SaveMarkdown(TempFile Markdown)
        {

            Markdown.File = Path.Combine(KeyValueConfig.FileSaveDir, Markdown.File);
            // 使用Markdig转换Markdown为HTML

            string htmlContent = md.SaveMarkdown(Markdown) ?? "保存成功!";
            if (string.IsNullOrEmpty(htmlContent))
            {
                return Json("保存成功!");
            }
            return Json(htmlContent);
        }
        public new ActionResult User()
        {

            var users = SL.db.Login;
            List<Login> list = users.Where(d => d.username == LoginMode.username).ToList();
            return View("UserList", list);
        }

        public ActionResult PutUser([FromBody] Login mode)
        {

            var users = SL.db.Login.FirstOrDefault(d => d.username == mode.username);
            if (users != null)
            {
                if (!LoginMode.admin)
                {
                    mode.LV = users.LV;

                }
                if (LoginMode.LV != "1")
                {
                    mode.role = users.role;
                }
                try
                {
                    SL.db.Entry(users).CurrentValues.SetValues(mode);
                    SL.db.SaveChanges();

                }
                catch (Exception)
                {
                    return Json(new Result("修改失败"));
                    throw;
                }

                return Json(new Result("修改成功", 1));
            }

            return Json(new Result("修改失败"));
        }

    }
    public class TempFile
    {

        public string File { get; set; }

        public string Content { get; set; }
    }
    public enum DirType
    {
        /// <summary>
        /// 视图
        /// </summary>
        View,
        /// <summary>
        /// 部分视图
        /// </summary>
        PartialView
    }
}